<!DOCTYPE html>
<style>
p {
    font:20px/1 Ahem;
    margin:.2em;
}
.vlr {
    -webkit-writing-mode:vertical-lr;
}
.vrl {
    -webkit-writing-mode:vertical-rl;
}
</style>
<p title="LTR"><span>12 345 6789</span></p>
<p title="RTL" dir=rtl><span>12 345 6789</span></p>
<p title="VERTICAL-LR" class=vlr><span>12 345 6789</span></p>
<p title="VERTICAL-RL" class=vrl><span>12 345 6789</span></p>
<div id=log></div>
<script>
Array.prototype.forEach.call(document.querySelectorAll("p"), function (e) {
    testOffsetFromPoint(e.firstChild, e.title);
    e.style.textRendering = "optimizeLegibility";
    testOffsetFromPoint(e.firstChild, e.title + " (Complex Path)");
});

function testOffsetFromPoint(element, name) {
    var writingMode = getComputedStyle(element).webkitWritingMode;
    var isVertical = writingMode && writingMode[0] == "v";
    var results = [ name ];
    getOffsetFromPoint(element, isVertical, results);
    if (isVertical) // The last character in vertical is flaky by win/mac/linux
        results.splice(-1, 1);
    for (var result of results) {
        var div = document.createElement("div");
        div.innerText = result;
        log.appendChild(div);
    }
}

function getOffsetFromPoint(element, isVertical, results) {
    if (isVertical) {
        var x = element.offsetLeft + element.offsetWidth / 2;
        var ymin = element.offsetTop;
        var width = element.offsetHeight;
    } else {
        var y = element.offsetTop + element.offsetHeight / 2;
        var xmin = element.offsetLeft;
        width = element.offsetWidth;
    }
    var lastCharacterOffset = null;
    var lastPosition = null;
    for (var position = -1; position <= width + 1; ++position) {
        if (isVertical)
            y = ymin + position;
        else
            x = xmin + position;
        var result = document.caretRangeFromPoint(x, y);
        var characterOffset = result ? result.startOffset : null;
        if (characterOffset === lastCharacterOffset)
            continue;
        var advance = position - lastPosition;
        results.push(characterOffset + "=" + position + " (" + advance + ")");
        lastCharacterOffset = characterOffset;
        lastPosition = position;
    }
    return results;
}

if (window.testRunner)
    testRunner.dumpAsText();
</script>
